package com.supconit.its;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.supconit.its.environment.Environment;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * mybatis-plus 代码生成辅助类
 * </p>
 *
 * @author 史金涛
 * @date 2020/8/7 13:08
 */
public class CodeGenerator {

    /* 用于LocalDatetime格式转换 */
    final private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * <p>
     * LocalDateTime转为string
     * </p>
     *
     * @param localDateTime LocalDateTime格式的数据
     * @return {@link String }
     * @author shijintao@supconit.com
     * @date 2020/6/15 13:28
     */
    public static String convertLocalDateTime(LocalDateTime localDateTime) {
        return dateTimeFormatter.format(localDateTime);
    }

    public static void main(String[] args) throws IOException {
        // 初始化 Environment
        Environment.init();

        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        String projectPath = Environment.PROJECT_PATH + "codegenerator\\";
        globalConfig.setOutputDir(projectPath + Environment.mavenSource)
                .setAuthor(Environment.AUTHOR)
                .setOpen(false)
                // XML ResultMap
                .setBaseResultMap(true)
                // XML columLisL
                .setBaseColumnList(true)
                .setSwagger2(true);

        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(Environment.URL)
                .setDriverName(Environment.DRIVER_NAME)
                .setUsername(Environment.USERNAME)
                .setPassword(Environment.PASSWORD);

        // 包配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo
                .setModuleName(Environment.MODULE_NAME)
                .setService("service")
                .setServiceImpl("service.impl")
                .setEntity("domain.po")
                .setXml("mapper")
                .setMapper("dao")
                .setParent(Environment.PACKAGE)
                .setDto("domain.dto")
                .setVo("domain.vo");

        // -------------------------------------- 这里可以自定义各个类的名称生成格式, %s 作为占位符

        globalConfig
                .setControllerName("%sController")
                .setServiceName("%sService")
                .setServiceImplName("%sServiceImpl")
                .setEntityName("%sPO")
                .setMapperName("%sDao")
                .setXmlName("%sMapper")
                .setQueryPageDTOName("Query%sPageDTO")
                .setQueryListDTOName("Query%sListDTO")
                .setQueryDTOName("Query%sDTO")
                .setQueryListVOName("Query%sListVO")
                .setQueryPageVOName("Query%sPageVO");

        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                //自定义属性注入:abc
                //在.ftl(或者是.vm)模板中，通过${cfg.abc}获取属性
                Map<String, Object> map = new HashMap<>();
                // entityNam
                map.put("entityLowCase", Environment.entityName);
                // EntityName
                map.put("entityUpCase", Environment.entityUpCase);
                // module path
                map.put("domainPath", Environment.PACKAGE + "." + Environment.MODULE_NAME + ".domain");
                // localDateTime
                map.put("localDateTime", convertLocalDateTime(LocalDateTime.now()));
                this.setMap(map);
            }
        };

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();


        // 配置自定义输出模板
        // 指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig
                .setController("/templates/controller/controller.java")
                .setService("/templates/service/service.java")
                .setServiceImpl("/templates/service/impl/serviceImpl.java")
                .setMapper("/templates/dao/dao.java")
                .setXml("/templates/mapper/mapper.xml")
                .setEntity("/templates/domain/po/po.java");

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setEntityLombokModel(true)
                .setRestControllerStyle(true)
                .setEntitySerialVersionUID(true)
                .setInclude(Environment.TABLE_NAME).setControllerMappingHyphenStyle(true)
                .setTablePrefix(packageInfo.getModuleName() + "_");


        strategy.setNameConvert(new INameConvert() {
            @Override
            public String entityNameConvert(TableInfo tableInfo) {
                return Environment.MAPPED_ENTITY_NAME;
            }

            @Override
            public String propertyNameConvert(TableField field) {
                return null;
            }
        });

        autoGenerator
                .setStrategy(strategy)
                .setPackageInfo(packageInfo)
                .setTemplate(templateConfig)
                .setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setTemplateEngine(new VelocityTemplateEngine())
                .setCfg(injectionConfig)
                .execute();
    }

}
